/**
 * $Revision: 1.0 $
 * $Author: Eric Yang $
 * $Date: Aug 7, 2009 10:38:54 PM $
 *
 * Author: Eric Yang
 * Date  : Aug 7, 2009 10:38:54 PM
 *
 */
package com.gooex.service.base.impl;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.c4j.string.StringTools;
import org.c4j.system.web.exception.ServiceException;
import org.c4j.system.web.hibernate.BaseHibernateService;

import com.gooex.domain.base.Category;
import com.gooex.domain.common.Region;
import com.gooex.service.base.ICategoryManager;
import com.gooex.service.base.exception.CategoryException;
import com.gooex.service.base.exception.ExceptionCode;

/**
 * @author Eric Yang
 * @version 1.0
 */
public class CategoryManagerImpl extends BaseHibernateService implements ICategoryManager {

	public Category getCategory(String id) {
		if (StringTools.isNotBlankOrNull(id)) {
			Object category = getHibernateTemplate().get(Category.class, id);
			if (category != null)
				return (Category) category;
		}
		return null;
	}

	public Category assertCategory(String id) {
		Category category = getCategory(id);
		if (category != null)
			return category;
		throw new ServiceException(ExceptionCode.CATEGORY_NOT_EXISTS, "");
	}

	public List<Category> getCategorys() {
		return getHibernateTemplate().find("from Category");
	}

	public Category getCategoryByName(String name) {
		String hql = "from " + Category.class.getName() + " where name=?";
		List<Category> categorys = getHibernateTemplate().find(hql, name);
		if (categorys != null && categorys.size() == 1)
			return categorys.get(0);
		return null;
	}

	public void saveCategory(Category category) throws ServiceException {
		if (StringTools.isBlankOrNull(category.getId())) {
			throw new ServiceException(ExceptionCode.CATEGORY_ID_NULL, "");
		}

		if (category.getParent() == null || StringTools.isBlankOrNull(category.getParent().getId())) {
			category.setParent(null);
		}
		getHibernateTemplate().saveOrUpdate(category);
	}

	public void removeCategory(Category category) throws CategoryException {
		Category parent = category.getParent();
		if (parent != null) {
			parent.getChildren().remove(category);
		}
		getHibernateTemplate().delete(category);
	}

	public List<Category> getCategories(Category parent) {
		return getCategories(parent, -1);
	}

	public List<Category> getCategories(Category parent, int num) {
		Criteria criteria = getSession().createCriteria(Category.class).setCacheable(true);
		if (parent == null || StringTools.isBlankOrNull(parent.getId())) {
			criteria = criteria.add(Restrictions.isNull("parent"));
		} else {
			criteria = criteria.add(Restrictions.eq("parent", parent));
		}
		if (num > 0)
			criteria = criteria.setFirstResult(num);

		criteria = criteria.addOrder(Order.desc("count"));
		return criteria.list();
	}

	public List<Category> getSubCategoriesByName(Category parent, String name) {
		Criteria criteria = getSession().createCriteria(Category.class).setCacheable(true);
		if (parent == null || StringTools.isBlankOrNull(parent.getId())) {
			criteria = criteria.add(Restrictions.isNull("parent"));
		} else {
			criteria = criteria.add(Restrictions.eq("parent", parent));
		}
		criteria = criteria.add(Restrictions.like("name", "%" + name + "%"));

		criteria = criteria.addOrder(Order.desc("count"));
		return criteria.list();
	}

	public List<Category> getMenuTopCategories() {
		List<Category> result = getCategories(null);
		if (result != null && result.size() > 0)
			return result;
		return new ArrayList<Category>();
	}

	public List<Category> getCateChildren(String id) {
		Category parent = getCategory(id);
		return getCategories(parent, -1);
	}

	public void increaseCount(Category category, String region) {
		category = getCategory(category.getId());
		if (category == null)
			return;
		category.increaseCount(region);
		getHibernateTemplate().saveOrUpdate(category);
		Category parent = category.getParent();
		if (parent != null)
			increaseCount(parent, region);
	}

	public void decreaseCount(Category category, String region) {
		category = getCategory(category.getId());
		if (category == null)
			return;
		category.decreaseCount(region);
		getHibernateTemplate().saveOrUpdate(category);
		Category parent = category.getParent();
		if (parent != null)
			decreaseCount(parent, region);
	}

}
